REM GO EDITOR using John Hind's application framework
REM Copyright (C) 1993 John Tromp

APP Go
	TYPE 3
	PATH "\GO"
	EXT "GO"
	ICON "\GO\Go.ico"
ENDA

PROC Go:
	GLOBAL bw%,bh%,bs%	REM board width,height,size
	GLOBAL gb%					REM go board, stone bitmap
	GLOBAL eb%,db%			REM empty/dot bitmaps
	GLOBAL sr%,sd%,nd%	REM stone radius/diameter, neighbour distance
	GLOBAL bwp%,bhp%		REM board width/height in pixels
	GLOBAL maxnv%				REM max # non-visible pixels
	GLOBAL mv%(512),mn% REM moves, move number
	GLOBAL bd%(880)			REM board data sets
	GLOBAL cx%,cy%			REM cursor x/y
	GLOBAL pt%(440)			REM point type
	GLOBAL uf%(440)			REM union find
	GLOBAL log%(4096)		REM union/find log
	GLOBAL clix%				REM log index
	GLOBAL ogb%,osb%		REM overview go board/stones
	GLOBAL obwp%,obhp%	REM overview board width/height
	GLOBAL komi					REM 2nd move compensation
	GLOBAL name$(128)		REM file name
	GLOBAL changed%			REM remember to save
	GLOBAL ten%					REM prepare for rank>=10
	GLOBAL ko%(512)			REM forbidden moves
	LOCAL x%,y%

	db%=gCREATEBIT(4,4)
	gCLS
	gAT 1,1 :gLINEBY 1,0
	osb%=gCREATEBIT(15,5)
	gCLS :gAT 2,2 :gLINEBY 1,0
	gAT 5,0 :gINVERT 5,5
	gAT 10,0 :gINVERT 5,5
	gAT 11,1 :gFILL 3,3,1
	komi=5.5
	log%(1)=0
	x%=22 :y%=22
	pt%(x%)=3
	pt%(x%-21)=-1 :pt%(y%-1)=-1
	DO
		x%=x%+1 :y%=y%+21
		pt%(x%-21)=-1 :pt%(y%-1)=-1
		pt%(x%)=4 :pt%(y%)=6
	UNTIL x%=41
	sr%=3 :maxnv%=15
	bw%=9 :bh%=9
	newstns:
	
 LOADM "\OPO\FRAMELIB.OPO"			REM Load the Application Framework code
 fAutoOff:											REM Allow automatic switch-off
 fRun:($330,"LSBEPNDTOKRCX",0)	REM Run application
ENDP

PROC aHkX%:		REM Callback to exit application on PSION-X
 RETURN 100		REM "Exit from application" message
ENDP

PROC aMh5%:		REM Callback for "Printable key pressed" message
	IF fParm%=32
		forward%:
		RETURN 0
	ENDIF
	IF fParm%=49 AND bh%>=10
		torow:(ten%+1)
		ten%=10-ten%
	ELSEIF fParm% >= 48 AND fParm% < 58
		torow:(ten%+fParm%-48)
		ten%=0
	ELSE
		fParm%=fParm% AND $FFDF
		IF fParm%>=%A AND fParm%<=%T
			tocol:(fParm%-%A-(fParm%<%J))
			ten%=0
		ELSE
			BEEP 2,300
		ENDIF
	ENDIF
	RETURN 0
ENDP

PROC aMh6%:		REM Callback for "Special key pressed" message
	IF fParm%=$100 :up:
	ELSEIF fParm%=$101 :down:
	ELSEIF fParm%=$102 :right:
	ELSEIF fParm%=$103 :left:
	ELSEIF fParm%=8  :back:
	ELSEIF fParm%=13 :move:
	ELSE BEEP 2,300
	ENDIF
	RETURN 0
ENDP

PROC aMh9%:		REM Callback for "Menu key pressed" message
	LOCAL k%
 
	mINIT
	mCARD "File","Load",%L,"Save as",%S
	mCARD "Play","Begin",%B,"End",%E,"Pass",%P,"Notate",%N
	mCARD "Display","Dimensions",%D,"Scrolling",%T,"Overview",%O
	mCARD "Special","Komi",%K,"Remove",%R,"Count",%C,"Exit",%x
	k%=fMenu%:                          REM Show menu (NOTE: bug fixed version of MENU)
	IF k%=0				REM Menu aborted by user
		RETURN 0		REM Return null command
	ELSE
		fParm%=k%		REM Parameter for "Hotkey pressed" message
		RETURN 4		REM "Hotkey pressed" message
	ENDIF
ENDP

PROC aMh10%:		REM Callback for "Help key pressed" message
	dINIT "Help: Go Editor"
	dTEXT "","Use cursor keys to move"
	dTEXT "","or type the coordinates"
	dTEXT "","Shift increases cursor movement"
	dTEXT "","Enter to place stone"
	dTEXT "","Delete/Space to go back/forward"
	fLock:
	DIALOG
	fUnlock:
	RETURN 0
ENDP

PROC aHkN%:
	GIPRINT CHR$(cx%+%A+(cx%<10))+GEN$(bh%+1-cy%,2)
	RETURN 0
ENDP

PROC aHkK%:
	dINIT "Set komi"
	dFLOAT komi,"Komi:",0,256
	fLock:
	DIALOG
	fUnlock:
	RETURN 0
ENDP REM setkomi

PROC aHkC%:
	LOCAL p%,s%,ws
	GLOBAL wc%,bc%
	GIPRINT "Counting..."
	p%=pos%:(bw%,bh%)
	DO
		s%=bd%(p%)
		IF s%=0 :s%=4 :ENDIF
		bd%(p%+440)=s%
		p%=p%-1
	UNTIL p%<21
	p%=pos%:(bw%,bh%)
	DO
		DO
			s%=bd%(p%+440)
			IF s%=4
				s%=whose%:(p%)
				IF s%=1 OR s%=2
					assign:(p%,s%)
				ENDIF
			ENDIF
			IF s%=1
				bc%=bc%+1
			ELSEIF s%=2
				wc%=wc%+1
			ENDIF
			p%=p%-1
		UNTIL pt%(p%)=-1
		p%=p%+bw%-20
	UNTIL p%<21
	overvw:(440)
	ws=wc%+komi
	dINIT "Score"
	dTEXT "White:",GEN$(ws,5)
	dTEXT "Black:",GEN$(bc%,5)
	IF ws>bc%
		dTEXT "","White wins"
	ELSEIF bc%>ws
		dTEXT "","Black wins"
	ELSE dTEXT "","Jigo"
	ENDIF
	fLock:
	DIALOG
	fUnlock:
	RETURN 0
ENDP REM count

PROC torow:(r%)
	IF r%>=1 AND r%<=bh%
		cy%=bh%+1-r%
		mvcur:
	ENDIF
ENDP

PROC tocol:(c%)
	IF c%>=1 AND c%<=bw%
		cx%=c%
		mvcur:
	ENDIF
ENDP

PROC whose%:(p%)
	LOCAL s%
	IF pt%(p%)=-1 :RETURN 0 :ENDIF
	s%=bd%(p%+440)
	IF s%<4 :RETURN s% :ENDIF
	bd%(p%+440)=0
	RETURN whose%:(p%-21) OR whose%:(p%+1) OR whose%:(p%+21) OR whose%:(p%-1)
ENDP REM whose

PROC assign:(p%,s%)
	IF pt%(p%)=-1 OR bd%(p%+440) :RETURN :ENDIF
	bd%(p%+440)=s%
	assign:(p%-21,s%)
	assign:(p%+1,s%)
	assign:(p%+21,s%)
	assign:(p%-1,s%)
ENDP REM assign

PROC aHkL%:
	LOCAL ret%
	name$="\GO\*.go"
	dINIT "Load file"
	dFILE name$,"File:",0
	fLock:
	ret%=DIALOG
	fUnlock:
	IF ret%=0 :RETURN 0 :ENDIF
	fParm$=name$
	RETURN 102
ENDP

PROC aOpen%:		REM Callback for file opening
	LOCAL ret%,fh%,x%,y%

	name$=fParm$
	ret%=IOOPEN(fh%,name$,0)
	IF ret%<0
		GIPRINT ERR$(ret%)
		RETURN -3
	ENDIF
	ret%=IOREAD(fh%,ADDR(mv%()),2)
	x%=PEEKB(ADDR(mv%()))
	y%=PEEKB(ADDR(mv%())+1)
	IF x%<2 OR x%>19 OR y%<2 OR y%>19
		GIPRINT "Illegal board size"
		IOCLOSE(fh%)
		RETURN -3
	ENDIF
	resize:(x%,y%)
	ret%=IOREAD(fh%,ADDR(mv%()),1024)
	IF ret%=-36
		ret%=0 :REM premature eof (bug)
	ENDIF
	GIPRINT GEN$(ret%/2,3)+" moves read"
	IOCLOSE(fh%)
	changed%=0
	RETURN 0
ENDP

PROC aCreate%:		REM Callback for file creation
 name$=fParm$
 changed%=1
 aHkD%:
 RETURN 0
ENDP

PROC aClose%:		REM Calback for file closing
	LOCAL ret%

	IF changed%
		fLock:
		ret%=ALERT("Save changes?","","No","Yes")
		fUnlock:
		IF ret%=2
	 		aHkS%:
		ENDIF
	ENDIF
	RETURN 0
ENDP

PROC aHkS%:
	LOCAL bytes%,m%,i&,fh%
	m%=0
	WHILE mv%(m%+1) :m%=m%+1 :ENDWH
	i&=mn%
	dINIT "Save file"
	dFILE name$,"Name:",17
	dLONG i&,"Moves:",0,m%
	fLock:
	m%=DIALOG
	fUnlock:
	IF m%=0
		GIPRINT "Not saved"
		RETURN 0
	ENDIF
	IF UPPER$(RIGHT$(name$,3))<>".GO"
		name$=name$+".go"
	ENDIF
	m%=IOOPEN(fh%,name$,$102)
	IF m%<0
		GIPRINT ERR$(m%)
		RETURN -1
	ENDIF
	bytes%=256*bh%+bw%
	IOWRITE(fh%,ADDR(bytes%),2)
	bytes%=2*i&
	m%=IOWRITE(fh%,ADDR(mv%()),bytes%)
	IF m%<0
		GIPRINT ERR$(m%)
		RETURN -1
	ENDIF
	GIPRINT "Game saved"
	changed%=0
	IOCLOSE(fh%)
	RETURN 0
ENDP REM save

PROC aHkO%:
	overvw:(0)
	RETURN 0
ENDP

PROC overvw:(off%)
	LOCAL dx%,y%,p%,s%
	gUSE ogb%
	gCLS
	y%=1
	DO
		dx%=0 :gAT 0,4*(y%-1)
		p%=pos%:(1,y%)
		DO
			s%=5*bd%(p%+dx%+off%)
			gCOPY osb%,s%,0,5,5,0
			dx%=dx%+1 :gMOVE 4,0
		UNTIL dx%=bw%
	y%=y%+1
	UNTIL y%>bh%
	gUSE gb%
ENDP REM overvw

PROC aHkB%:
	emptybrd:(0)
	drawbrd:
	RETURN 0
ENDP REM start

PROC emptybrd:(off%)
	LOCAL i%
	i%=1
	DO
		bd%(i%+off%)=0
		i%=i%+1
	UNTIL i%>440
	clix%=1 :mn%=0
ENDP REM emptybrd

PROC up:
	IF cy%>1
		IF fKmod% AND 2
			cy%=MAX(cy%-6,1)
		ELSE
			cy%=cy%-1
		ENDIF
		mvcur:
	ENDIF
ENDP REM up

PROC down:
	IF cy%<bh%
		IF fKmod% AND 2
			cy%=MIN(cy%+6,bh%)
		ELSE
			cy%=cy%+1
		ENDIF
		mvcur:
	ENDIF
ENDP REM down

PROC right:
	IF cx%<bw%
		IF fKmod% AND 2
			cx%=MIN(cx%+6,bw%)
			curret:
		ELSE
			cx%=cx%+1
			gMOVE nd%,0
		ENDIF
	ENDIF
ENDP REM right

PROC left:
	IF cx%>1
		IF fKmod% AND 2
			cx%=MAX(cx%-6,1)
			curret:
		ELSE
			cx%=cx%-1
			gMOVE -nd%,0
		ENDIF
	ENDIF
ENDP REM left

PROC move:
	GLOBAL root%
	LOCAL p%,s%,ret%,cap%
	p%=pos%:(cx%,cy%)
	IF bd%(p%) OR p%=ko%(mn%+1)
		BEEP 9,100
		RETURN
	ENDIF
	IF fParm%=13
		changed%=1
	ENDIF
	mn%=mn%+1
	s%=2-(mn% AND 1)
	play:(cx%,cy%,s%)
	root%=p% :ufset:(root%,0)
	ko%(mn%+1)=0
	cap%=neighbr%:(p%-21,cx%,cy%-1,s%)+2*neighbr%:(p%+1,cx%+1,cy%,s%)+4*neighbr%:(p%+21,cx%,cy%+1,s%)+8*neighbr%:(p%-1,cx%-1,cy%,s%)
	IF uf%(root%)=0
		capture%:(cx%,cy%,s%)
		cap%=16
	ENDIF
	mv%(mn%)=cx%+256*cy%
	clix%=clix%+1
	log%(clix%)=cap%
	curret:
ENDP REM move

PROC neighbr%:(p%,x%,y%,s%)
	LOCAL ns%,nr%
	IF pt%(p%)=-1 :RETURN 0: ENDIF
	ns%=bd%(p%)
	IF ns%=0
		ufset:(root%,uf%(root%)-1) REM add liberty
		ko%(mn%+1)=-1
		RETURN 0
	ENDIF
	nr%=p%
	WHILE uf%(nr%)>0
		nr%=uf%(nr%)
	ENDWH
	IF ns%=s%
		IF nr%=root%
			ufset:(nr%,uf%(nr%)+1)
		ELSE
			ns%=uf%(root%)+uf%(nr%)+1
			IF uf%(root%) < uf%(nr%)
				ufset:(root%,ns%)
				ufset:(nr%,root%)
			ELSE
				ufset:(nr%,ns%)
				ufset:(root%,nr%)
				root%=nr%
			ENDIF
		ENDIF
		ko%(mn%+1)=-1
		RETURN 0
	ENDIF
	IF uf%(nr%)=-1
	  IF capture%:(x%,y%,ns%)=1 AND ko%(mn%+1)=0
	  	ko%(mn%+1)=p%
	  ELSE
	  	ko%(mn%+1)=-1
	  ENDIF
	  RETURN 1
	ENDIF
	ufset:(nr%,uf%(nr%)+1)
	RETURN 0
ENDP REM neighbr

PROC ufset:(i%,v%)
	clix%=clix%+2
	log%(clix%)=i%
	log%(clix%-1)=uf%(i%)
	uf%(i%)=v%
ENDP REM ufset

PROC back:
	LOCAL p%,s%,i%
	IF mn%=0 :BEEP 10,100 :RETURN :ENDIF
	p%=mv%(mn%)
	s%=2-(mn% AND 1)
	mn%=mn%-1
	IF p%=-1
		GIPRINT "Pass"
		RETURN
	ENDIF
	cx%=PEEKB(ADDR(mv%(mn%+1)))
	cy%=PEEKB(ADDR(mv%(mn%+1))+1)
	p%=pos%:(cx%,cy%)
	mvcur:
	i%=log%(clix%)
	clix%=clix%-1
	IF i%=16
		fill:(cx%,cy%,s%)
	ELSE
		play:(cx%,cy%,s%)
		IF i% AND 1 :fill:(cx%,cy%-1,3-s%) :ENDIF
		IF i% AND 2 :fill:(cx%+1,cy%,3-s%) :ENDIF
		IF i% AND 4 :fill:(cx%,cy%+1,3-s%) :ENDIF
		IF i% AND 8 :fill:(cx%-1,cy%,3-s%) :ENDIF
	ENDIF
	DO
		i%=log%(clix%)
		IF i%<20 :BREAK :ENDIF
		uf%(i%)=log%(clix%-1)
		clix%=clix%-2
	UNTIL 0
	play:(cx%,cy%,0)
	curret:
ENDP REM back

PROC aHkE%:
	IF forward%:
		RETURN 0
	ENDIF
	RETURN 4
ENDP

PROC forward%:
	LOCAL p%,x%,y%
	mn%=mn%+1
	p%=mv%(mn%)
	IF p%=-1
		GIPRINT "Pass"
	ELSE
		x%=PEEKB(ADDR(mv%(mn%)))
		y%=PEEKB(ADDR(mv%(mn%))+1)
		p%=pos%:(x%,y%)
		mn%=mn%-1
		IF x%=0 OR x%>bw% OR y%=0 OR y%>bh%
			BEEP 4,400
			RETURN -1
		ENDIF
		IF bd%(p%) OR p%=ko%(mn%+1)
			BEEP 7,100
			RETURN -1
		ENDIF
		cx%=x% :cy%=y%
		mvcur:
		move:
	ENDIF
	RETURN 0
ENDP REM forward

PROC fill:(x%,y%,s%)
	LOCAL p%
	p%=pos%:(x%,y%)
	IF bd%(p%) OR pt%(p%)=-1 :RETURN :ENDIF
	play:(x%,y%,s%)
	fill:(x%,y%-1,s%)
	fill:(x%+1,y%,s%)
	fill:(x%,y%+1,s%)
	fill:(x%-1,y%,s%)
ENDP REM fill

PROC aHkR%:
	capture%:(cx%,cy%,bd%(pos%:(cx%,cy%)))
	curret:
	RETURN 0
ENDP REM delete

PROC capture%:(x%,y%,col%)
	LOCAL p%,s%
	p%=pos%:(x%,y%)
	s%=bd%(p%)
	IF s%=0 OR pt%(p%)=-1 :RETURN 0 :ENDIF
	IF s%<>col%
		WHILE uf%(p%)>0
			p%=uf%(p%)
		ENDWH
		ufset:(p%,uf%(p%)-1)
		RETURN 0
	ENDIF
	play:(x%,y%,0)
	p%=1+capture%:(x%,y%-1,col%)+capture%:(x%+1,y%,col%)+capture%:(x%,y%+1,col%)+capture%:(x%-1,y%,col%)
	RETURN p%
ENDP REM capture

PROC aHkP%:
	changed%=1
	mn%=mn%+1
	mv%(mn%)=-1
	ko%(mn%+1)=0
	GIPRINT "Pass"
	RETURN 0
ENDP REM pass

PROC aHkT%:
	LOCAL maxnv&
	maxnv&=maxnv%
	dINIT "Scrolling"
	dLONG maxnv&,"Edge visibility:",0,39
	fLock:
	DIALOG
	fUnlock:
	IF maxnv&<>maxnv%
		maxnv%=maxnv&
		vscroll:
	ENDIF
	RETURN 0
ENDP REM scroll

PROC drawbrd:
	LOCAL p%,dx%,y%,s%
	gUPDATE OFF
	gCLS
	IF sr%=1
		drawdots:
	ELSE
		drwlines:
	ENDIF
	y%=1
	DO
		dx%=0 :p%=pos%:(1,y%)
		DO
			s%=bd%(p%+dx%)
			IF s% OR pt%(p%+dx%)=7
				play:(dx%+1,y%,s%)
			ENDIF
			dx%=dx%+1
		UNTIL dx%=bw%
	y%=y%+1
	UNTIL y%>bh%
	mvcur:
	CURSOR gb%,0,3,3
	gUPDATE ON
ENDP REM drawbrd

PROC drawdots:
	gPATT db%,bwp%,bhp%,3
ENDP REM drawdots

PROC drwlines:
	LOCAL i%
	i%=sr%
	DO
		gAT i%,sr%
		gLINEBY 0,bhp%-sd%+1
	i%=i%+nd%
	UNTIL i%>=bwp%
	i%=sr%
	DO
		gAT sr%,i%
		gLINEBY bwp%-sd%,0
	i%=i%+nd%
	UNTIL i%>=bhp%
ENDP REM drwlines

PROC play:(x%,y%,s%)
	LOCAL p%,t%
	p%=pos%:(x%,y%)
	bd%(p%)=s%
	bat:(x%,y%)
	t%=s%
	IF t%=0
		t%=pt%(p%)
	ENDIF
	gCOPY eb%,t%*sd%,0,sd%,sd%,3
ENDP REM play

PROC aHkD%:
	LOCAL bw&,bh&,neww%,newh%,oldsr%,ret%
	bw&=bw%
	bh&=bh%
	oldsr%=sr%
	dINIT "Dimensions"
	dLONG bw&,"Board Width:",2,19
	dLONG bh&,"Board Height:",2,19
	dCHOICE sr%,"Stone Size:","3,5,7,9,11"
	fLock:
	ret%=DIALOG
	fUnlock:
	IF ret%=0 :RETURN 0 :ENDIF
	neww%=bw& :newh%=bh&
	IF oldsr%<>sr%
		newstns:
	ENDIF
	IF neww%<>bw% OR newh%<>bh% OR bs%=0
		resize:(neww%,newh%)
	ELSE
		newbrd:
	ENDIF
	RETURN 0
ENDP REM board

PROC newstns:
	LOCAL i%
	sd%=2*sr%+1
	nd%=sd%+1
	IF eb% :gCLOSE(eb%) :ENDIF
	eb%=gCREATEBIT(12*nd%,nd%)
	gCLS
	IF sr%=1
		i%=1
		DO
			gAT i%,1 :gLINEBY 1,1
			i%=i%+3
		UNTIL i%>36
		gAT 3,0 :gFILL 3,3,1 :gINVERT 3,3
		gAT 6,0 :gFILL 3,3,2
		RETURN
	ENDIF
	gAT sr%,0 :gLINEBY 0,sd%
	gAT 0,sr% :gLINEBY sd%,0
	gAT 3*sd%+sr%,sr% :gBOX sd%+nd%,sd%
	gAT 4*sd%+sr%,sr% :gLINEBY 0,sd%
	gAT 6*sd%+sr%,0 :gLINEBY 0,nd%
	gAT 7*sd%+sr%,0 :gLINEBY 0,nd%
	gAT 8*sd%+sr%,0 :gLINEBY 0,nd%
	gAT 6*sd%+sr%,sr% :gLINEBY 2*sd%,0
	gAT 9*sd%+sr%,-sr% :gBOX sd%+nd%,sd%
	gAT 10*sd%+sr%,0 :gLINEBY 0,sr%
	IF sr%=2
		gAT 7*sd%+sr%,sr% :gFILL 1,1,1
	ELSE
		gAT 7*sd%+sr%-1,sr%-1 :gFILL 3,3,0
	ENDIF
	gAT sd%,0
	IF sr%<4
		gINVERT sd%,sd%
	ELSE
		gBORDER 0,sd%,sd%
		gMOVE 1,1
		gFILL sd%-2,sd%-2,0
	ENDIF
	gAT 2*sd%,0
	IF sr%<4
		gINVERT sd%,sd%
		gMOVE 1,1
		gFILL sd%-2,sd%-2,1
	ELSE
		gBORDER 0,sd%,sd%
	ENDIF
ENDP REM newstns

PROC border:(w%,h%,m%)
	LOCAL i%,e%
	i%=pos%:(1,h%)
	pt%(i%)=6-3*m%
	pt%(i%+21)=m% OR 6
	e%=i%+w%-1
	WHILE i%<e%
		i%=i%+1
		pt%(i%)=10 AND m%
		pt%(i%+21)=-1 AND m%
	ENDWH
	i%=21+w%
	pt%(i%)=(m% AND 5) OR 4
	pt%(i%+1)=m% OR 4
	WHILE i%<e%
		i%=i%+21
		pt%(i%)=8 AND m%
		pt%(i%+1)=-1 AND m%
	ENDWH
	pt%(e%)=11 AND m%
ENDP REM border

PROC resize:(w%,h%)
	LOCAL bs9%,bs13%,bs19%
	IF bw% :border:(bw%,bh%,0) :ENDIF
	bw%=w% :bh%=h%
	bs%=bw%*bh%
	obwp%=4*bw%+1 :obhp%=4*bh%+1
	IF ogb% :gCLOSE(ogb%) :ENDIF
	ogb%=gCREATE(240-obwp%,0,obwp%,obhp%,1)
	bs9%=(bw%=9) AND (bh%=9) AND 7
	bs13%=(bs%=169) AND 7
	bs19%=(bs%= 361) AND 7
	pt%(pos%:( 3, 3))=bs9%
	pt%(pos%:( 3, 7))=bs9%
	pt%(pos%:( 7, 3))=bs9%
	pt%(pos%:( 7, 7))=bs9% OR bs13%
	pt%(pos%:( 4, 4))=bs13% OR bs19%
	pt%(pos%:( 4,10))=bs13% OR bs19%
	pt%(pos%:( 4,16))=bs19%
	pt%(pos%:(10, 4))=bs13% OR bs19%
	pt%(pos%:(10,10))=bs13% OR bs19%
	pt%(pos%:(10,16))=bs19%
	pt%(pos%:(16, 4))=bs13% OR bs19%
	pt%(pos%:(16,10))=bs19%
	pt%(pos%:(16,16))=bs13% OR bs19%
	border:(bw%,bh%,-1)
	IF bw%>=6 AND bh%>=6
		cx%=4 :cy%=4
	ELSE
		cx%=1 :cy%=1
	ENDIF
	emptybrd:(0)
	newbrd:
ENDP REM resize

PROC newbrd:
	bwp%=bw%*nd%-1
	bhp%=bh%*nd%-1
	IF gb%
		gCLOSE(gb%)
	ENDIF
	gb%=gCREATE(0,0,bwp%,bhp%,1)
	drawbrd:
ENDP REM newbrd

PROC bat:(x%,y%)
	gAT (x%-1)*nd%,(y%-1)*nd%
ENDP REM bat

PROC curret:
	gAT cx%*nd%-sr%-3,cy%*nd%-sr%-3
ENDP REM curret

PROC mvcur:
	curret:
	vscroll:
ENDP REM mvcur

PROC vscroll:
	LOCAL nv%
	nv%=gY-39
	IF bhp%<=80 :RETURN :ENDIF
	IF nv%<=maxnv%
		gSETWIN 0,0
	ELSEIF bhp%-80-nv%<=maxnv%
		gSETWIN 0,80-bhp%
	ELSE
		gSETWIN 0,-nv%
	ENDIF
ENDP REM vscroll

PROC pos%:(x%,y%)
	RETURN x%+21*y%
ENDP REM pos%
